package com.hot12345.common.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class XmlProperties {
	
	private final static Log logger = LogFactory.getLog(XmlProperties.class);

	private URL sourceURL;
	private boolean timingReload;
	
	/**
	 * 配置来源URL
	 */
	private URL src = null;
	
	/**
	 * url 表达式中的protocol
	 */
	private String protocol = null;
	
	/**
	 * 配置来源对象, 根据protocol的不同而不同
	 */
	private File targetSrc = null;
	
	/**
	 * 记录文件最后一次修改时间
	 */
	private long lastModifiedTime = 0;
	
	/**
	 * 保存配置信息的map
	 */
	protected Map<String, Object> props = new ConcurrentHashMap<String, Object>(100);
	
	/**
	 * 初始化
	 */
	public final void initialize() {
		
		logger.info("开始初始化配置文件["+this.getSourceURL()+"], 执行类["+this.getClass().getName()+"]");		
		src = getSourceURL();
		if (null == src) {
			String errorMsg = "无法定位配置文件, 配置文件对象为null异常";
			logger.error(errorMsg);
			throw new RuntimeException(errorMsg);
		}
		
		protocol = src.getProtocol();
		if ("file".equals(protocol)) { 
			targetSrc = new File(src.getPath()); 
			lastModifiedTime = targetSrc.lastModified();
			FileInputStream fin = null;
			try {
				fin = new FileInputStream(targetSrc);
				props = reload(fin, props);
			} catch (Exception iex) {
				throw new RuntimeException("重新加载配置异常", iex);
			} finally {
				if (null != fin) {
					try { fin.close(); } catch (Exception ioex) { }
				}
			}
		} else if ("jar".equals(protocol)) {
			String[] info = src.getPath().split("\\!");
			targetSrc = new File(info[0].substring(5)); 
			lastModifiedTime = targetSrc.lastModified();
			JarFile jf = null;
			try {
				jf = new JarFile(targetSrc, false, ZipFile.OPEN_READ);
				ZipEntry ze = jf.getEntry(info[1].substring(1));
				props = reload(jf.getInputStream(ze), props);
			} catch (Exception ex) {
				throw new RuntimeException("创建jar文件异常", ex);
			} finally {
				if (null != jf) {
					try { jf.close(); } catch (IOException e) { }
				}
			}
		}
			
		
	}
	
	protected Map reload(InputStream in, Map tarStorage) {
 
		try {
			Map rtv = XmlUtil.toMap(in);
			return rtv;
		} catch (Exception ex) {
			logger.error("Exception",ex);
		}
		
		return tarStorage;
	}
	
	public Map<String, Object> getProperties() {
		
		return this.props;
	}

	public boolean isTimingReload() {
		return timingReload;
	}

	public void setTimingReload(boolean timingReload) {
		this.timingReload = timingReload;
	}

	public URL getSourceURL() {
		return sourceURL;
	}

	public void setSourceURL(URL sourceURL) {
		this.sourceURL = sourceURL;
	}
}
